package com.zyy.game.tianlong;

import com.alibaba.fastjson.JSON;
import com.zyy.game.tianlong.network.SocketMsg;
import com.zyy.game.tianlong.network.codec.GameByteToMsgDecoder;
import com.zyy.game.tianlong.network.codec.GameMsgToByteEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 并发连接测试
 *
 * @author relufi
 */
@Slf4j
public class ServerTestMaxConnection {
    @AllArgsConstructor
    static class IdChannel {
        public Channel channel;
        public int id;
    }

    private static List<IdChannel> idChannels = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup workGroup = new NioEventLoopGroup(15);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> workGroup.shutdownGracefully().syncUninterruptibly()));
        int count = testMax(workGroup, 0);
        Scanner scanner = new Scanner(System.in);
        while (true) {
            if (scanner.hasNextLine()) {
                String s = scanner.nextLine();
                count = testMax(workGroup, count);
            }
        }
    }

    static int testMax(EventLoopGroup workGroup, int count) {
        int nowCount = count + 200;
        workGroup.execute(() -> {
            for (IdChannel idChannel : idChannels) {
                idChannel.channel.writeAndFlush(new SocketMsg(0, 0, JSON.toJSONString(new TestMsg(Integer.toString(idChannel.id)))));
            }
        });
        for (int i = count; i < nowCount; i++) {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) {
                            ch.pipeline()
                                    .addLast(new GameMsgToByteEncoder())
                                    .addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
                                    .addLast(new GameByteToMsgDecoder((ctx, cause) -> {
                                        log.debug("0.0", cause);
                                    }))
                                    .addLast(new SimpleChannelInboundHandler<SocketMsg>() {
                                        @Override
                                        protected void channelRead0(ChannelHandlerContext ctx, SocketMsg msg) {
                                            System.out.println(msg);
                                        }
                                    });
                        }
                    });
            ChannelFuture sync = bootstrap.connect(new InetSocketAddress(6666)).syncUninterruptibly();
            Channel channel = sync.channel();
            idChannels.add(new IdChannel(channel, i));
            channel.writeAndFlush(new SocketMsg(0, 0, JSON.toJSONString(new TestMsg(Integer.toString(i)))));
//                channel.closeFuture().sync();
        }
        return nowCount;
    }
}
